package third_components

import (
	"crypto/hmac"
	"encoding/hex"
	"errors"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"golang.org/x/crypto/ripemd160"
	"project_api/user_web/global"
	"project_api/user_web/models"
	"time"
)

func SetToken(uToken string, userId int32, expire int64) bool {
	if uToken == "" {
		return false
	}
	uKey := global.ServerConfig.UserTokenKey
	uTokenNew := hashHMACRIPEMD160(uToken, []byte(uKey))

	UtModel := models.UserToken{
		UserId:     userId,
		Token:      uTokenNew,
		CreateTime: time.Now().Unix(),
		ExpireTime: expire,
	}

	if err := global.DB.Create(&UtModel).Error; err != nil {
		zap.S().Errorw("[SetToken] error inserting into user_token", "msg", err.Error())
		return false
	}

	return true
}

// GetToken 用于查询并处理用户的Token信息
func GetToken(uToken string) (gin.H, error) {
	var userTokenModel models.UserToken
	userResData := make(gin.H)

	uKey := global.ServerConfig.UserTokenKey
	uTokenNew := hashHMACRIPEMD160(uToken, []byte(uKey))

	// 查询Token是否存在
	uTokenResult := global.DB.Where(&models.UserToken{Token: uTokenNew}).First(&userTokenModel)
	if uTokenResult.Error != nil {
		// 如果查询出错，返回错误
		return nil, uTokenResult.Error
	}

	// 如果Token存在且有效
	if uTokenResult.RowsAffected != 0 {
		if userTokenModel.ExpireTime == 0 || userTokenModel.ExpireTime > time.Now().Unix() {
			// Token有效，返回相关信息
			userResData["token"] = uTokenNew
			userResData["user_id"] = userTokenModel.UserId
			userResData["expiretime"] = userTokenModel.ExpireTime
			userResData["expires_in"] = getExpiredIn(userTokenModel.ExpireTime)
			return userResData, nil
		} else {
			// Token已过期，删除Token记录
			deleteResult := global.DB.Where(&models.UserToken{Token: uTokenNew}).Delete(&userTokenModel)
			if deleteResult.Error != nil {
				return nil, deleteResult.Error
			}
		}
	}

	// 返回用户的Token信息
	return nil, errors.New("token is not expired")
}

func hashHMACRIPEMD160(data string, key []byte) string {
	// 使用 HMAC-RIPEMD160
	h := hmac.New(ripemd160.New, key)
	h.Write([]byte(data))
	hash := h.Sum(nil)
	return hex.EncodeToString(hash) // 转换为十六进制字符串
}

// getExpiredIn 计算剩余的过期时间
func getExpiredIn(expireTime int64) int64 {
	if expireTime == 0 {
		return 365 * 86400
	}
	currentTime := time.Now().Unix() // 获取当前时间的 Unix 时间戳
	return maxInt64(0, expireTime-currentTime)
}

// max 返回两个整数中的较大值
func maxInt64(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}
